///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2007-2009 ILOG, S.A.
//  All Rights Reserved.
//  The following is ILOG Source Code.  No modifications may be made to the  
//  ILOG Source Code.  Any usage of the ILOG Source Code is subject to 
//  the terms and conditions of the ILOG End User License Agreement   
//  applicable to this ILOG software product.
//
///////////////////////////////////////////////////////////////////////////////

package ilog.gauges.gaugesClasses.circular
{
  import ilog.utils.MathUtil;
  
  /**
   * The <code>CircularScaleRelatedRenderer</code> is the base class for visual 
   * circular elements that need a scale to position themselves, like needles or tracks. 
   *  
   * @mxml
   *  
   * <p>The <code>&lt;CircularScaleRelatedRenderer&gt;</code> tag inherits all the properties
   * of its parent classes and adds the following properties:</p>
   *  
   * <pre>
   * &lt;CircularScaleRelatedRenderer
   *   <strong>Properties</strong>
   *   scale="<i>IScale, No Default</i>"
   *  /&gt;
   * </pre>
   * 
   * @see ilog.gauges.gaugesClasses.circular.ICircularScale
   */  
  public class CircularScaleRelatedRenderer extends CircularGaugeElement
  {
    /**
     * Constructor.
     */    
    public function CircularScaleRelatedRenderer()
    {
      super();
    }
    
    private var _startAngleRadians:Number;

    /**
     * The start angle, in radians, of the related scale, in the <code>[0, 2*Math.PI]</code> interval.
     */    
    final protected function get startAngleRadians():Number
    {
      return _startAngleRadians;
    }

    private var _endAngleRadians:Number;

    /**
     * The end angle, in radians, of the related scale, in the <code>[0, 2*Math.PI]</code> interval.
     */    
    final protected function get endAngleRadians():Number
    {
      return _endAngleRadians;
    }

    private var _totalAngleRadians:Number;
    
    /**
     * The total angle range, in radians, of the related scale, in the <code>[0, 2*Math.PI</code>] interval.
     */    
    final protected function get totalAngleRadians():Number
    {
      return _totalAngleRadians;
    }

    /**
     *  @private
     */    
    override protected function commitProperties():void
    {
      super.commitProperties();
      if (scale)
      {
        _startAngleRadians = MathUtil.mod2PI(MathUtil.toRadians(scale.startAngle)); 
        _endAngleRadians = MathUtil.mod2PI(MathUtil.toRadians(scale.endAngle));
        if (startAngleRadians == endAngleRadians)
          _totalAngleRadians = 2 * Math.PI;
        else
          _totalAngleRadians = computeAngle(_startAngleRadians, _endAngleRadians, 
                                            scale.orientation); 
      }
    }
    
    private var _scale:ICircularScale;
   
    private var _scaleSet:Boolean = false;

    [Inspectable(category="Gauge")]

    /**
     * The scale that relates to this gauge element. If the <code>scale</code>
     * property is not explicitely set, the first scale of the holding
     * gauge will be used.
     *
     * @default null
     * 
     * @see ilog.gaugesClasses.GaugeBase#scales
     */  
    public function get scale():ICircularScale
    {
      // auto discovery, do we have an explicit scale? If not do we have
      // scales[0] as a scale? If not let's use it.
      if (!_scaleSet && gauge.scales.length > 0 && _scale != gauge.scales[0]) {
        // set it explicitely to register the element.
        setScale(gauge.scales[0]);
      }
      return _scale;
    }
    
    /**
     * @private
     */
    public function set scale(value:ICircularScale):void
    {
      if (value != _scale) {
        setScale(value);  
      }
      _scaleSet = (value != null);
    }

    /**
     * @private
     */
    private function setScale(value:ICircularScale):void 
    {
      if (_scale != null)
        _scale.unregisterElement(this);
      _scale = value;
      if (_scale != null) 
        _scale.registerElement(this);      
    }

    /**
     * @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
      super.updateDisplayList(unscaledWidth, unscaledHeight);
      graphics.clear();
    }
    
  }
}
